#include <cmath>

#include <shape.h>
#include <cursor.h>
#include <control.h>
#include <canvas.h>

#include <rectangle.h>

#include <iostream>

using namespace std;

Cursor cursor;

static guint idle = 0;
static int n = 0;

static gboolean
idle_update (gpointer data)
{
	gtk_widget_queue_draw (GTK_WIDGET (data));

	return FALSE;
}

static CairoRegion *
get_region (CairoContext *context)
{
	CairoRectangleList *rectangles;
	CairoRegion *region;
	int i;

	rectangles = cairo_copy_clip_rectangle_list (context);

	if (rectangles->status == CAIRO_STATUS_CLIP_NOT_REPRESENTABLE)
	{
		cairo_rectangle_int_t clip_rectangle;
		cairo_rectangle_list_destroy (rectangles);

		if (!gdk_cairo_get_clip_rectangle (context, &clip_rectangle))
		{
			return NULL;
		}
	}

	region = cairo_region_create ();

	for (i = rectangles->num_rectangles - 1; i >= 0; --i)
	{
		CairoRectangle *rectangle = &rectangles->rectangles[i];
		cairo_rectangle_int_t clip_rectangle;

		clip_rectangle.x = floor (rectangle->x);
		clip_rectangle.y = floor (rectangle->y);
		clip_rectangle.width = ceil (rectangle->width);
		clip_rectangle.height = ceil (rectangle->height);

		if (cairo_region_union_rectangle (region, &clip_rectangle) != CAIRO_STATUS_SUCCESS)
		{
			cairo_region_destroy (region);
			region = NULL;
			break;
		}
	}

	cairo_rectangle_list_destroy (rectangles);

	return region;
}

static void
update (gpointer widget)
{
	if (idle)
	{
		g_source_remove (idle);
	}

	idle = g_idle_add_full (G_PRIORITY_HIGH_IDLE, idle_update, widget, NULL);
}

static Rectangle rectangle(20.0, 20.0, 100.0, 100.0);

static gboolean
draw (GtkWidget *widget, CairoContext *context, gpointer data)
{
	rectangle.draw (context);

	return TRUE;
}

static gboolean
motion (GtkWidget *widget, GdkEventMotion *event, gpointer data)
{
	cursor.x = event->x;
	cursor.y = event->y;

	update ((gpointer) widget);

	return TRUE;
}

static gboolean
press (GtkWidget *widget, GdkEventButton *event, gpointer data)
{
	cursor.pressed = true;

	update ((gpointer) widget);

	return TRUE;
}

static gboolean
release (GtkWidget *widget, GdkEventButton *event, gpointer data)
{
	cursor.pressed = false;

	update ((gpointer) widget);

	return TRUE;
}

static gboolean
key (GtkWidget *widget, GdkEventKey *event, gpointer data)
{
	cout << "key"<< endl;

	return TRUE;
}

GtkWidget *
canvas_new ()
{
	GtkWidget *canvas;

	canvas = gtk_layout_new (NULL, NULL);

	gtk_widget_set_double_buffered (canvas, TRUE);

	gtk_widget_set_events (canvas, 0);

	gtk_widget_add_events (canvas,
												 GDK_EXPOSURE_MASK |
												 GDK_BUTTON_PRESS_MASK |
												 GDK_BUTTON_RELEASE_MASK |
												 GDK_POINTER_MOTION_MASK |
												 GDK_BUTTON_MOTION_MASK |
												 GDK_KEY_PRESS_MASK);

	g_signal_connect (G_OBJECT (canvas), "draw", G_CALLBACK (draw), NULL);
	g_signal_connect (G_OBJECT (canvas), "motion-notify-event", G_CALLBACK (motion), NULL);
	g_signal_connect (G_OBJECT (canvas), "button-press-event", G_CALLBACK (press), NULL);
	g_signal_connect (G_OBJECT (canvas), "button-release-event", G_CALLBACK (release), NULL);
	g_signal_connect (G_OBJECT (canvas), "key-press-event", G_CALLBACK (key), NULL);

	return canvas;
}
